
#ifndef __CAMERA_H__
#define __CAMERA_H__

#include "Real3.h"
#include "RenderState.h"

struct D3DXMATRIX; 
class BBox;

class Camera
{
public:

	// Constructor
	Camera();

	// Set Variables
	void SetPosition(Real3 pos);
	void SetDirection(Real3 dir);
	void SetUp(Real3 _up);
	void SetRight(Real3 _right);

	// Resets all the variables
	void Reset();

	// Return variables
	Real3 Position() { return position; }
	Vector3 Direction() { return direction; }
	Vector3 Up() { return up; }
	Vector3 Right() { return right; }

	// Change directions
	void RotateRight(float theta);
	void RotateUp(float theta);
	void RotateCW(float theta);

	// Move camera
	void MoveForward(float dist);
	void MoveRight(float dist);
	void MoveUp(float dist);

	// Sets position and direction to look at a bounding box
	void LookAt(BBox *box);

	// View Matrix
	D3DXMATRIX *ViewMatrix(); 

	// Projection Matrix
	D3DXMATRIX *ProjMatrix(); 

	// Speed for moving camera
	float linearSpeed; // meters / iteration
	float rotationalSpeed; // ratians / iteration
	short xSensitivity;
	short ySensitivity;

	// Writes to a file
	void Write(FileStream &file);
	void Read(FileStream &file);

	// Sets the screen resolution
	void SetResolution(ushort _width, ushort _height);
	void SetWidth(ushort _width) { width = _width; }
	void SetHeight(ushort _height) { height = _height; }

	// Returns the resolutions
	ushort Width() const { return width; }
	ushort Height() const { return height; }
	
	// Zoom level
	float GetZoom() { return zoomLevel; }
	void SetZoom(float lev);
	void IncreaseZoom(float lev);

	// Returns the aspect ratio
	float AspectRatio() { return ((float)width)/((float)height); }

	// Set Fullscreen
	void SetFullScreen(bool _full) { fullscreen = _full; }

	// Returns fullscreen
	bool FullScreen() const { return fullscreen; }

	// Handle 1st person screen movement
	void FirstPersonMovement();

private:

	// Variables to determine position and direction of viewing
	Real3 position;
	Vector3 direction;
	Vector3 up;
	Vector3 right;

	// Flag to update view matrix
	bool updateView;
	bool updateFOV;

	// Projection Matrix
	D3DXMATRIX *projMatrix; 

	// Method for engine to call to move the camera
	void MoveCamera();

	// Method that draws camera stats to the screen
	void DrawCameraStats();

	// Sets the necessary variables to update
	void UpdateCamera();

	// Rotates the camera
	void RotateCamera();

	// Screen Resolution
	ushort width;
	ushort height;
	
	// Zoom Level
	float zoomLevel;

	// Fullscreen
	bool fullscreen;

	friend class STATE(MainMenu);
	friend class STATE(CreateGame);
	friend class STATE(JoinGame);
	friend class STATE(Settings);
	friend class STATE(_3D);
	friend class STATE(Loading);
};

#endif // __CAMERA_H__
